package project;

import java.io.IOException;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.List;

import jade.core.AID;
import jade.core.Agent;
import jade.core.behaviours.SimpleBehaviour;
import jade.lang.acl.ACLMessage;
import jade.lang.acl.MessageTemplate;
import jade.lang.acl.UnreadableException;

public class Agent3 extends Agent {

	MessageTemplate mt1 = MessageTemplate.and(MessageTemplate.MatchPerformative(ACLMessage.INFORM),
			MessageTemplate.MatchSender(new AID("Agent2", AID.ISLOCALNAME)));

	protected void setup() {

		addBehaviour(new SimpleBehaviour(this) {

			public void action() {

				while (Ag12.bool) {

					if (Ag23.ListaValoriDistincte != null) {
						List<List<DateFiltrate>> result = formeazaListe(0, Ag23.ListaValoriDistincte, Ag23.listaAparate);
						Ag34.listaDePosibilitati = ScoateInformatiiImposibile(result);

						Ag23.ListaValoriDistincte = null;
					} else {
						if (Ag12.bool != true) {

							ACLMessage msg1 = Ag23.mesaj;

							if (msg1 != null) {
								try {
									System.out.println("AG3 - " + myAgent.getLocalName() + " <- " + msg1.getContentObject());
								} catch (UnreadableException e) {
									System.out.println("Exception in Agent3");
									e.printStackTrace();
								}

								ACLMessage reply = msg1.createReply();
								reply.setPerformative(ACLMessage.INFORM);
								try {
									reply.setContentObject((Serializable) interpretData((List<Data>) msg1.getContentObject()));
								} catch (IOException e) {
									// TODO Auto-generated catch block
									e.printStackTrace();
								} catch (UnreadableException e) {
									// TODO Auto-generated catch block
									e.printStackTrace();
								}
								Ag23.mesaj = null;

							} else
								block();
						}
					}
				}
			}

			@Override
			public boolean done() {
				// TODO Auto-generated method stub
				return false;
			}

		});

	}

	private List<List<Data>> interpretData(List<Data> datas) {
		for (Data data : datas) {

		}
		return new ArrayList(Arrays.asList(new Data[] { new Data(15, "text"), new Data(48, "dsfojkds;f") }));

	}

	private static Boolean ListaEValida(List<DateFiltrate> lista) {
		for (int i = 0; i < lista.size() - 2; i++)
			for (int j = i + 1; j < lista.size(); j++) {
				if (lista.get(i).getAparat() == lista.get(j).getAparat() && lista.get(i).isStatus() == lista.get(j).isStatus())
					return false;
				if (lista.get(i).getAparat() == lista.get(j).getAparat() && lista.get(i).isStatus() && !lista.get(j).isStatus())
					break;
				if (lista.get(i).getAparat() == lista.get(j).getAparat() && !lista.get(i).isStatus() && lista.get(j).isStatus())
					break;
			}
		return true;

	}

	private static List<List<DateFiltrate>> formeazaListe(int p, List<Data> listaIntrare, List<Data> listaAparate) {
		List<List<DateFiltrate>> result = new ArrayList<List<DateFiltrate>>();
		List<DateFiltrate> listaRez = new ArrayList<DateFiltrate>();
		AdaugaAparate(result, -1, listaIntrare, listaAparate, listaRez);
		return result;
	}

	private static void AdaugaAparate(List<List<DateFiltrate>> result, int i, List<Data> listaIntrare, List<Data> listaAparate,
			List<DateFiltrate> listaRez) {
		i++;
		if (i < listaIntrare.size() - 1) {
			int diff = listaIntrare.get(i + 1).getValue() - listaIntrare.get(i).getValue();
			for (Data element : listaAparate) {
				if (element.getValue() == Math.abs(diff)) {
					if (diff > 0)
						listaRez.add(new DateFiltrate(diff, listaIntrare.get(i).getTime(), element.getTime(), listaIntrare.get(i).getValue(), true));
					else
						listaRez.add(new DateFiltrate(diff, listaIntrare.get(i).getTime(), element.getTime(), listaIntrare.get(i).getValue(), false));
					AdaugaAparate(result, i, listaIntrare, listaAparate, CopyOf(listaRez));
					listaRez.remove(listaRez.size() - 1);
				}
			}
			return;
		}
		result.add(listaRez);
	}

	private static List<DateFiltrate> CopyOf(List<DateFiltrate> lista) {
		List<DateFiltrate> result = new ArrayList<DateFiltrate>();
		for (DateFiltrate el : lista)
			result.add(el);
		return result;
	}

	private static List<List<DateFiltrate>> ScoateInformatiiImposibile(List<List<DateFiltrate>> liste) {
		List<List<DateFiltrate>> result = new ArrayList<List<DateFiltrate>>();
		for (List<DateFiltrate> lista : liste)
			if (ListaEValida(lista))
				result.add(lista);
		return result;
	}
}
